//-------------------------------------------------------------------
//	Copyright (c) 2013  Zhirnov Andrey
//	This file is part of the "Noise Library" project.
//	See copyright notice in "linNoiseCL.h".
//-------------------------------------------------------------------

#pragma once

#include <Includes.h>
#include "../Source/CSource.h"
#include <stdio.h>

namespace Noise
{

	//
	// Program
	//

	class CProgram : protected CReferenced
	{
	// types
	public:
		struct Format
		{
			EPixelFormat	fmt;
			EPixelType		type;
		};
		STATIC_ASSERTE( sizeof(Format) == sizeof(int)*2 );


	// variables
	protected:
		CSource::TFunctionData	_srcData;
		EBuildOptions			_options;
		EPixelFormat			_format;
		vec3					_coordScale;
		vec3					_coordBias;
		bool					_enableViewer;


	// methods
	private:
		void _Release()		{ delete this; }

		static bool _OpenFile (const char *filename, FILE *&file);

		static void _SaveBitmap (const uvec2 &dim, const uni_array<const uint8> &data, const char *filename);
		static void _SaveBitmapPackedFloat (const uvec2 &dim, const uni_array<float> &data, const char *filename);
		static void _SaveBitmapCustomFloat (const uvec3 &dim, const uni_array<const uint8> &data, const char *filename);
		
	protected:
		bool _PreBuild (CSourcePtr source, CSource::TPreBuildData &data) const;
		bool _Build (const CSource::TPreBuildData &data, CSource::TFunctionData &funcData) const;

		static uint _GetBytePerPixel (EPixelFormat format, EPixelType type);

	public:
		CProgram ();
		virtual ~CProgram ();

		virtual void Delete ();

		virtual EResult Build (CSourcePtr source, EBuildOptions options);

		virtual EResult SetInteger (EProgramParameter pname, const int *v, int count);
		virtual EResult SetReal (EProgramParameter pname, const real *v, int count);

		virtual EResult GetReal (EProgramQuery pname, real *v, int count) const;
		virtual EResult GetString (EProgramQuery pname, char *buf, int length) const;
		virtual EResult GetInteger (EProgramQuery pname, int *v, int count) const;
		
		virtual EResult RenderToImage (const uvec3 &dim, EPixelFormat format, EPixelType type, EImageType imageType, const char *filename);

		virtual EResult RenderToMemory (const uvec3 &dim, const uvec2 &sizes, EPixelFormat format, EPixelType type, void *pixels) = 0;
		virtual EResult RenderToImageCL (cl_mem imageId) = 0;
		virtual EResult RenderToSubImageCL (cl_mem imageId, const svec3 &offset, const svec3 &dim) = 0;
		virtual EResult RenderToTextureGL (GLenum target, GLuint id, int level) = 0;
		virtual EResult RenderToTextureDX (void *dxTex) = 0;
	};

	SHARED_POINTER( CProgram );

}	// Noise
